#ifdef	ADI_OLD

#ifndef	_INPUT_SEQUENCE_H_
#define _INPUT_SEQUENCE_H_


#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include "types.h"
#include "Match.h"
#include "WindowReader.h"

#define LOADED 1
#define SORTED 2

using namespace std;

/* Each Input-Sequence will be an array of pairs-of-bits
	(each pair represents one of the 'A', 'C', 'G', 'T' characters).
*/
class InputSequence
{
  private:

	size_t length;
	vector<SeqBlock> pairs;
	string seqName;

	// The block size in bits
	///static const uint CHARS_PER_BLOCK;
	
	/* flags indicating whether all jobs corresponding this sequence have been loaded and sorted */
	char loaded_sorted;
	
	/* counts the completed jobs */
	uint doneJobs;
	
  	/* The matches found by processing jobs corresponding this sequence */
	vector<vector<Match*>*> matches;

	// A window that will be used to read the string and see if a new job needs to be created
	WindowReader window;

	// The starting poisition of the window
	uint windowPos;
	

  public:
  	/* matches flatten & sorted */
	vector<Match*> sortedMatches;
  
	InputSequence();

	~InputSequence();

	void append(const char *arr, const uint arrLen);

	void setName(string& name);

	string getName() const;
	
	size_t getLength() const;

	char getChar(const size_t index) const;

	/* The returned sequence is reversed */
	SeqBlock getBlock(const size_t fromIndex) const;
	
	short getCharAsShort(const size_t index) const;
	
	bool trySort();
	
	inline char isSorted() const;
	
	inline char isLoaded() const;
	
	inline void addMatch(uint ind, Match *m);
	
	inline void notifyJobAdd();
	
	inline void notifyDone();
	
	inline void notifyLoaded();

#ifdef DEBUG
	void print() const;
#endif

};

inline char InputSequence::isSorted() const
{
	return loaded_sorted & SORTED;
}

inline char InputSequence::isLoaded() const
{
	return loaded_sorted & LOADED;
}

inline void InputSequence::addMatch(uint ind, Match *m)
{
	matches[ind]->push_back(m);
}

inline void InputSequence::notifyJobAdd()
{
	matches.push_back(new vector<Match*>());
}

inline void InputSequence::notifyDone()
{
	__sync_add_and_fetch (&doneJobs, 1);
}

inline void InputSequence::notifyLoaded()
{
	loaded_sorted |= LOADED;
}

#endif /* _INPUT_SEQUENCE_H_ */

#endif	/* ADI_OLD */
